#include "byhh.h"

#define DEBUG_BYHH

#include <QSettings>


using namespace byhh_variables;

byhh::byhh(Profile * newProfile, QString newName ):BBS(newProfile, newName) {
    connect (&Timer , SIGNAL(timeout()) , this , SLOT(clear()));
    Timer.start(5000);
    name = newName;
    profile = newProfile;
    connection = new QHttp(server.host() , server.port(80));
}

//用来释放已经完成功能的QHttp异步线程
void byhh::clear(void) {
    ///this function may could use qDeleteAll() ?
    QList<QHttp *> temp = toDelete;
    toDelete.clear();
    int i = temp.count();
    if (i > 0)
	qDebug() << tr("killing the threads : [%1]").arg(i);
    foreach (QHttp * http , temp)
	delete http;
}

//调用对话框提示输入id和password
void byhh::setIdPasswd(void){
    QWidget father;
    QString id = QInputDialog::getText ( & father, tr("Need ID "), tr("Input the ID for [%1]").arg(profile->getName()), QLineEdit::Normal, "" );
    QString pw = QInputDialog::getText ( & father, tr("Need password"), tr("Input the password for [%1]").arg(id), QLineEdit::Password, "123456" );
    profile->setUsername(id);
    profile->setPassword(pw);
}

//启动连接
void byhh::start(void){
    if (state != Stop) return;
    DEBUG_F();
    if (profile->getOption("isGuestMode")){
	state = Running;
	refreshMe();
	return;
    }
    emit newStatus(101, "Examing cookies stored...");
    state = Starting;
    if (profile->getUsername() == "" || profile->getPassword() == "")  setIdPasswd();
    ///refresh the old cookies
    QByteArray query = queryAllBoard.toUtf8();
    connect (connection , SIGNAL(requestFinished(int , bool)) , this , SLOT(verifyCookie(int , bool)));
    request (connection, profile, query);
}

//断开连接
void byhh::stop(void){
    if (state != Running) return;
    state = Stopping;
    logout();
}

void byhh::restart(void){
    if (state != (Stop|Running)) return;
    logout();
    login();
}

void byhh::login(){
    DEBUG_F();
    ///This functin is to log into the byhh.net
    emit newStatus(103, tr("Trying to login '%1'...").arg(name));
    QByteArray query = queryToLogin.arg(profile->getUsername()).arg(profile->getPassword()).toUtf8();
    connect (connection , SIGNAL(requestFinished(int , bool)) , this , SLOT(checkLogin(int , bool)));
    request(connection, profile, query);
}

void byhh::logout(){
    DEBUG_F();
    ///This functin is to log out the byhh.net
    emit newStatus(111, tr("Trying to logout '%1'...").arg(name));
    QByteArray query = queryToLogout.toUtf8();
    request(connection, profile, query);
    emit newStatus(112, tr("Logout '%1' successful.").arg(name));
    state = Stop;
}

//检测上一次的登录信息是否依然有效。若无效则新登录。
void byhh::verifyCookie(int num , bool error){
    QString html = fetchHtml(num , error, connection);
    if (html == "") return;
    DEBUG_F();
    disconnect (connection , SIGNAL(requestFinished(int , bool)) , this , SLOT(verifyCookie(int , bool)));
    profile->updateCookie(html);
    if (profile-> checkLogin()){
	qDebug() << ">> verify cookie OK.";
	state = Running;
	emit newStatus(104, tr("Login '%1' successful!").arg(name));
	refreshMe();
    }
    else{
	qDebug() << ">> Cookies seared. Sending login message.";
	emit newStatus(102, tr("Cookies seared. Sending login message."));
	login();
    }
}

/*
 * 打开登录页面，发送登录信息
 */
void byhh::checkLogin(int num , bool error){
    QString html = fetchHtml(num , error, connection);
    if (html == "") return;
    DEBUG_F();
    //qDebug() << html;
    profile->updateCookie(html);
    disconnect (connection , SIGNAL(requestFinished(int , bool)) , this , SLOT(checkLogin(int , bool)));
    if (profile->checkLogin()){
	emit newStatus(104, tr("Login '%1' successful!").arg(name));
	state = Running;
	refreshMe();
    }
    else{
	emit newStatus(105, tr("Login '%1' Failed.").arg(name));
	state = Stop;
    }
}

void byhh::refreshMe(){
    ///This functin is to get a newer board list
    if (state != Running) return ;
    DEBUG_F();
    connection->abort();
    emit newStatus(121, tr("Checking new boards on '%1'...").arg(name));
    //QHttp * http;
    QByteArray query;
    if (profile->getOption("isGuestMode")){
	//This is when we are a guest user
	for (int i = 0 ; i < 12 ; i ++){
	    connect (connection , SIGNAL(requestFinished(int , bool)) , this , SLOT(extractGuestBoard(int , bool)));
	    query = queryViewBBS.arg(i).toUtf8();
	    request(connection, profile, query);
	}
	return;
    }
    connect (connection , SIGNAL(requestFinished(int , bool)) , this , SLOT(extractAllBoard(int , bool)));
    query = queryAllBoard.toUtf8();
    request(connection, profile, query);
}

void byhh::extractGuestBoard(int num , bool error){
    //this was called mostly because it's in GuestMode
    static bool reset = false;
    static int count = 12;
    QString html = fetchHtml(num , error, connection);
    if (html == "") return;
    DEBUG_F();
    if (--count < 1)
	reset = true;
    if (reset){
	disconnect (connection , SIGNAL(requestFinished(int , bool)) , this , SLOT(extractGuestBoard(int , bool)));
	count = 12;
	reset = false;
    }    
    profile-> updateCookie(html);
    int pos = 0;
    byhhBoard * one;
    QRegExp exp("board=([^>]+)> \\S+ ([^<]+)</a>");
    while ( (pos = exp.indexIn(html , pos)) != -1){
	one = new byhhBoard;
	one -> id = exp.cap(1) ;
	one -> name = exp.cap(2);
	one -> setProfile(profile);
	if (!addBoard(one))
	    delete one;
	else 
	    emit newStatus(122, tr("Got a new board '%1' on bbs '%2'.").arg(one->name).arg(name));
	pos += exp.matchedLength();
    }
    emit refreshFinished(false);
}

void byhh::extractAllBoard(int num , bool error){
    ///To get board list(of all) from a html
    QString html = fetchHtml(num , error, connection);
    if (html == "") return;
    DEBUG_F();
    disconnect (connection , SIGNAL(requestFinished(int , bool)) , this , SLOT(extractAllBoard(int , bool)));
    profile-> updateCookie(html);
    int pos = 0;
    byhhBoard * one;
    QRegExp exp("name=[^ ]+ ([^>]*)><a href=bbsdoc.board=([^>]+)>[^\\(]+\\(([^\\)]+)\\)");
    while ( (pos = exp.indexIn(html , pos)) != -1){
	one = new byhhBoard;
	one -> id = exp.cap(2) ;
	one -> name = exp.cap(3);
	one -> setProfile(profile);
	if (exp.cap(1) == " checked"){
	    one -> favorite = true;
	}
// 	qDebug() << ">> get a board:" << one->name;
	if (!addBoard(one))
	    delete one;
	else
	    emit newStatus(122, tr("Got a new board '%1' on bbs '%2'.").arg(one->name).arg(name));
	pos += exp.matchedLength();
    } 
    qDebug() << ">> Now," << name << "has" << boardPool.count() << "boards.";
    emit refreshFinished(false);
}